package file

import (
	"context"
	"strconv"
	"strings"

	"mall/common/modelx"
	"mall/service/attachment/model"
	"mall/service/attachment/rpc/internal/svc"
	"mall/service/attachment/rpc/internal/utils/errorhandler"
	"mall/service/attachment/rpc/types/attachment"
	"mall/service/backend/common/errorx"
	"mall/service/backend/common/i18n"
	"mall/service/backend/common/utils/pointy"

	"github.com/zeromicro/go-zero/core/logx"
)

type BackendGetFileByIdLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewBackendGetFileByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BackendGetFileByIdLogic {
	return &BackendGetFileByIdLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *BackendGetFileByIdLogic) BackendGetFileById(in *attachment.FileIdReq) (*attachment.FileInfo, error) {
	if len(strings.TrimSpace(in.Id)) == 0 {
		return nil, errorx.NewInvalidArgumentError(i18n.ValidationError)
	}

	var id uint64
	if i, err := strconv.ParseInt(strings.TrimSpace(in.Id), 10, 64); err == nil {
		id = uint64(i)
	} else {
		return nil, errorx.NewInvalidArgumentError(i18n.ValidationError)
	}

	res, err := l.svcCtx.MediaFile.FindOne(l.ctx, id)
	if err != nil {
		return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
	}

	var meta []*attachment.MetaInfo
	if in.WithMeta != nil && *in.WithMeta > 0 {
		filterMap := make(map[string]map[string][]any)
		filterMap[model.AttachmentMetumColumns.AttachmentID] = map[string][]any{
			"equalTo": []any{id},
		}
		list, _, err := l.svcCtx.MediaFile.GetMeta(l.ctx, model.M{}, -1, filterMap)
		if err != nil {
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}

		if len(list) > 0 {
			for _, v := range list {
				if len(v.MetaKey) > 0 && v.MetaValue.Valid {
					meta = append(meta, &attachment.MetaInfo{
						Id:    pointy.GetPointer(v.MetaID),
						Key:   pointy.GetPointer(v.MetaKey),
						Value: pointy.GetPointer(v.MetaValue.String),
					})
				}
			}
		}
	}

	return &attachment.FileInfo{
		Id:            pointy.GetPointer(strconv.FormatUint(res.ID, 10)),
		AltText:       &res.PostTitle,
		Filename:      &res.PostName,
		Excerpt:       &res.PostExcerpt,
		Url:           &res.GUID,
		UserId:        pointy.GetPointer(strconv.FormatUint(res.PostAuthorID, 10)),
		ParentId:      &res.PostParentID,
		Type:          pointy.GetPointer(uint32(res.PostType)),
		MimeType:      &res.PostMimeType,
		Status:        pointy.GetPointer(uint32(res.PostStatus)),
		Sort:          pointy.GetPointer(uint32(res.MenuOrder)),
		Password:      &res.PostPassword,
		CommentStatus: pointy.GetPointer(uint32(res.CommentStatus)),
		CommentCount:  pointy.GetPointer(uint32(res.CommentCount)),
		Path:          &res.Path,
		Size:          &res.Size,
		Md5:           &res.MD5,
		CreatedAt:     pointy.GetPointer(modelx.FormatTime(res.PostDate, "")),
		UpdatedAt:     pointy.GetPointer(modelx.FormatTime(res.PostModifiedDate, "")),
		DeletedAt:     pointy.GetPointer(modelx.FormatNullDotTime(res.DeletedAt, "")),
		Meta:          meta,
	}, nil
}
